<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        .wrap {
            margin-bottom: 40px;
        }
    </style>
</head>

<body>

    <div id="app">
        <!-- vue响应式和数组 -->

        <p>list:{{list}}</p>
        <p> 
            <!-- 变更方法 -->
            <button @click="addEle">新增</button>
            <button @click="delEle">删除</button>
        </p>
        <p>
            <!-- 非变更方法 -->
            <button @click="filterEle">查找偶数</button>
        </p>
        <p>
            <!-- 数组遗留问题 -->
            <button @click="editEle">修改</button>
            <button @click="editLen">修改length</button>
        </p>
    </div>
</body>
<script>

    /* 
        Vue2的响应式本质依赖于Object.defineProperty(),对应data中挂载数据的键名绑定取值拦截和赋值拦截
        1. 如果直接对应属性名赋新值,可以被Vue响应式机制检测到
        2. 如果data属性的属性值是数组和对象, 直接修改数组和对象中数据, 不可以被Vue响应式机制检测到

        由于 JavaScript 的限制，Vue 不能检测数组和对象的变化  
            a. 其中 Vue已经做了一部分处理
            b. 还有一部分遗留问题  !!!!


        对于数组而言: 
            Vue 不能检测数组变化,为了解决这个问题,Vue将数组的方法分为变更方法和非变更方法分别做了不同处理
            1. 变更方法 => 调用该方法后会影响原数组的方法 (Vue 将被侦听的数组的变更方法进行了包裹，所以它们也将会触发视图更新)
                push()
                pop()
                shift()
                unshift()
                splice()
                sort()
                reverse()

            2. 非变更方法 => 调用该方法后不会影响原数组,而是返回新数组的方法
                slice()  concat()  map()  filter()  flat()

            Vue中数组遗留问题!!!
            Vue 不能检测以下数组的变动：
                当你利用索引直接设置一个数组项时，例如：vm.items[indexOfItem] = newValue
                当你修改数组的长度时，例如：vm.items.length = newLength
    
    */



    var vm = new Vue({
        el: "#app",
        data: {
            list: [1, 4, 7, 2, 5, 8, 3, 6, 9, 10],
        },
        methods: {
            addEle() {
                // 修改原数组
                var ele = Math.round(Math.random() * 100); // 随机元素
                this.list.push(ele);
            },
            delEle() {
                var index = Math.floor(Math.random() * this.list.length);
                this.list.splice(index, 1);
            },
            filterEle() {
                this.list = this.list.filter(v => v % 2 == 0);
            }, 

            editEle(){
                // 当你利用索引直接设置一个数组项时，例如：vm.items[indexOfItem] = newValue
                // this.list[1] = 444;
                // console.log("问题1",this.list);

                // (1) 换一个方法 splice(index,1,value);  => 数组的变更方法
                // this.list.splice(1,1,444);

                // (2) 对原数组进行拷贝, 将拷贝后的数组赋值原值  => 当使用非变更方法时，可以用新数组替换旧数组
                // this.list[1] = 444;
                // this.list = [...this.list];

                // (3) Vue中提供了强制更新视图的方法
                // this.list[1] = 444;
                // this.$forceUpdate();

                // (2) Vue中提供了修改对象数据的方法  (也会被Vue响应式检测到) 
                // this.$set(obj,key,val);
                this.$set(this.list, 1, 444);


            },
            editLen(){
                // 当你修改数组的长度时，例如：vm.items.length = newLength
                // this.list.length --;
                // console.log("问题2",this.list);

                // (1) 换一个方法 pop();  => 数组的变更方法
                // this.list.pop();

                // (2) 对原数组进行拷贝, 将拷贝后的数组赋值原值  => 当使用非变更方法时，可以用新数组替换旧数组
                // this.list.length --;
                // this.list = [...this.list];

                // (3) Vue中提供了强制更新视图的方法
                // this.list.length --;
                // this.$forceUpdate();
            }
        }

    })


    console.log(vm);

</script>

</html>